iT邦幫忙

2023 iThome 鐵人賽

DAY 13
0

Redux Toolkit

為了測試,我們把預設的專案改成使用 redux 的形式吧~
安裝 redux toolkit

npm install @reduxjs/toolkit react-redux

在src 底下新增名稱為 app 的資料夾 , 再新增一個 store.ts

// app/store.ts

import { configureStore } from "@reduxjs/toolkit";
import counterSlice from "./counterSlice";

const store = configureStore({
    reducer: {
        counter: counterSlice,
    },
});

export default store;

新增counterSlice.ts

// store/counterSlice.ts

import { createSlice } from "@reduxjs/toolkit";

export const initialState = {
    value: 0,
};

export const counterSlice = createSlice({
    name: 'counter',
    initialState,
    reducers: {
        increment: (state) => {
            state.value += 1;
        },
        decrement: (state) => {
            state.value -= 1;
        },
        reset : (state) => {
            state.value = 0;
        }

    },
});

export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;

main.tsx 加入 Provider

// src/main.tsx

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import { Provider } from 'react-redux'
import store from './app/store.ts'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>,
)

改寫 App.tsx

// App.tsx

import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './app/counterSlice'import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import { Provider } from 'react-redux'
import store from './app/store.ts'

function App() {
  const counter = useSelector((state: any) => state.counter.value)
  const dispatch = useDispatch()
  return (
    <>
      <div>
        <a href="https://vitejs.dev" target="_blank">
          <img src={viteLogo} className="logo" alt="Vite logo" />
        </a>
        <a href="https://react.dev" target="_blank">
          <img src={reactLogo} className="logo react" alt="React logo" />
        </a>
      </div>
      <h1>Vite + React</h1>
      count is {counter}
      <div className="card">
        <div>
          <button className="button" onClick={() => dispatch(increment())}>
            increment
          </button>
          <button className="button" onClick={() => dispatch(decrement())}>
            decrement
          </button>
        </div>
      </div>
      <p className="read-the-docs">
        Click on the Vite and React logos to learn more
      </p>
    </>
  )
}

export default App

那我們這個測試跟 useState 的測試其實很像,檢查狀態的更新使否正確,在測試Redux時,我們可以使用 store.getState()store.dispatch 來查看 store 狀態跟調用 action ,當然有使用async/await 也可以測試,結合 Day 10 的觀念就可以囉~

// counterSlice.test.ts

import store from ".";

describe("counterSlice", () => {

    it("should increment", () => {
        store.dispatch({ type: "counter/increment" });
        expect(store.getState().counter.value).toEqual(1);
    });
    
    it("should decrement", () => {
        store.dispatch({ type: "counter/decrement" });
        expect(store.getState().counter.value).toEqual(0);
    });
    
    it("should reset", () => {
        store.dispatch({ type: "counter/reset" });
        expect(store.getState().counter.value).toEqual(0);
    });
    
});

為了站著把錢掙了
我來公司只辦三件事,測試!測試!還是他媽的測試!
祝大家測試愉快~


上一篇
Day 12 - Component 測試
下一篇
Day 14 - userEvent 模擬使用者操作
系列文
React Clean Code And Unit Tests - 利用測試寫出人類看得懂的React程式30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言